home *** CD-ROM | disk | FTP | other *** search
/ EnigmA Amiga Run 1995 October / EnigmA AMIGA RUN 01 (1995)(G.R. Edizioni)(IT)[!][issue 1995-10][Aminet 7].iso / Aminet / util / sys / Replace_37_2.lha / Replace / Src / Replace.c < prev    next >
C/C++ Source or Header  |  1995-05-04  |  7KB  |  368 lines

  1. #include "Replace.h"
  2.  
  3. STXT VersTag[]        = "$VER: " VSTR;
  4. STXT CompileNo[]    = "Compiled on " __DATE__ " at " __TIME__;
  5. STXT Copyright[]    = "Copyright © 1994,95 Klaus Alexander Seistrup @ Magnetic Ink";
  6. STXT EMail[]        = "E-mail: kas@mink.ping.dk";
  7.  
  8. STXT LFFmt[]        = "%s\n";
  9.  
  10. CFG     GlobCFG;
  11.  
  12. TEXT RBuf[RBUFSIZE];
  13.  
  14.  
  15. Prototype LONG     stricmp(TEXT *,TEXT *);
  16. //
  17. LONG
  18. stricmp(s1,s2)
  19. TEXT *s1,*s2;
  20. {
  21.     return (Strnicmp(s1,s2));
  22. }
  23.  
  24.  
  25. Prototype LONG     strnicmp(TEXT *,TEXT *,LONG);
  26. //
  27. LONG
  28. strnicmp(s1,s2,n)
  29. TEXT *s1,*s2;
  30. LONG n;
  31. {
  32.     return (Strnicmp(s1,s2,n));
  33. }
  34.  
  35.  
  36. Prototype VOID     BadFile(TEXT *,TEXT *,TEXT *);
  37. //
  38. VOID
  39. BadFile(pgm,typ,fil)
  40. TEXT *pgm,*typ,*fil;
  41. {
  42.     extern volatile int errno;
  43.  
  44.     int err = errno;
  45.  
  46.     fprintf(stderr,"›33m%s:›0m Couldn't open %sput file ›3m%s›0m\n",pgm,typ,fil);
  47.     fprintf(stderr,"Error %ld: %s\n",err,strerror(err));
  48.     exit(10);
  49. }
  50.  
  51.  
  52. Prototype VOID     BadParm(TEXT *,TEXT *);
  53. //
  54. VOID
  55. BadParm(pgm,parm)
  56. TEXT *pgm,*parm;
  57. {
  58.     fprintf(stderr,"›33m%s:›0m Mandatory ›3m%s›0m parameter missing!\n",pgm,parm);
  59.     exit(10);
  60. }
  61.  
  62.  
  63.  
  64. Prototype VOID     About(VOID);
  65. //
  66. VOID
  67. About(VOID)
  68. {
  69.     fprintf(stderr,LFFmt,VersTag+6);
  70.     fprintf(stderr,LFFmt,CompileNo);
  71.     fprintf(stderr,LFFmt,Copyright);
  72.     fprintf(stderr,LFFmt,EMail);
  73. }
  74.  
  75.  
  76. Prototype VOID     Usage(TEXT *);
  77. //
  78. VOID
  79. Usage(pgm)
  80. TEXT *pgm;
  81. {
  82.     fprintf(stderr, \
  83. "›33mUSAGE:›0m ›1m%s›0m ›2m[›0m-i›3minFile›0m›2m] [›0m-o›3moutFile›0m›2m] <›0m-s›3msearchStr›0m›2m> <›0m-r›3mreplaceStr›0m›2m> [›0m-0›3mzeroAlias›0m›2m] [›0m-c›2m] [›0m-v›2m]›0m\n" \
  84. "\n" \
  85. "\t-›1mi›0m Optional ›3minput›0m file (default: stdin)\n" \
  86. "\t-›1mo›0m Optional ›3moutput›0m file (default: stdout)\n" \
  87. "\t-›1ms›0m Mandatory ›3msearch›0m string\n" \
  88. "\t-›1mr›0m Mandatory ›3mreplace›0m string\n" \
  89. "\t-›1m0›0m Set ASCII zero alias for search/replace (not yet implemented)\n" \
  90. "\t-›1mc›0m Use case-sensitive search routine (default: case-insensitive)\n" \
  91. "\t-›1mv›0m Verbose (report number of successful search/replace)\n",pgm);
  92.  
  93. }
  94.  
  95.  
  96. Prototype TEXT    *transmogrify(TEXT *);
  97. //
  98. TEXT *
  99. transmogrify(src)
  100. TEXT *src;
  101. {
  102.     TEXT *dst = src;
  103.     TEXT *ptr = dst;
  104.  
  105.     if (src)
  106.     {
  107.         BOOL flg = 0;
  108.         long len = 2;
  109.  
  110.         while (*ptr)
  111.         {
  112.             if (*ptr == 0x5C)    // BackSlash
  113.                 flg = 1;
  114.  
  115.             ++ptr;
  116.             ++len;
  117.         }
  118.  
  119.         if (flg)
  120.         {
  121.             TEXT c;
  122.  
  123.             dst = malloc(len);
  124.  
  125.             if (dst == NULL)
  126.             {
  127.                 fputs("Not enough memory!\n",stderr);
  128.                 exit(20);
  129.             }
  130.             ptr = dst;
  131.  
  132.             while (c = *src)
  133.             {
  134.                 if (c == 0x5C)
  135.                 {
  136.                     TEXT *tail;
  137.                     long v;
  138.  
  139.                     ++src;
  140.  
  141.                     switch (*src)
  142.                     {
  143.                         case 0x5C:
  144.                             *ptr = c;
  145.                             break;
  146.                         case 0x00:
  147.                             --src;
  148.                             break;
  149.                         default:
  150.                             v = strtol(src,&tail,0);
  151.                             
  152.                             if (v == 0)
  153.                             {
  154.                                 fputs("Conversion error - check escaped chars!\n",stderr);
  155.                                 exit(10);
  156.                             }
  157.                             *ptr = (TEXT) (v & 0x00FFL);
  158.                             src  = tail;
  159.                             --src;
  160.                     }
  161.                 }
  162.                 else
  163.                     *ptr = c;
  164.  
  165.                 ++src;
  166.                 ++ptr;
  167.             }
  168.             *ptr = 0;
  169.         }
  170.     }
  171.     return (dst);
  172. }
  173.  
  174. Prototype CFG    *InitCFG(LONG,TEXT **);
  175. //
  176. CFG *
  177. InitCFG(argc,argv)
  178. LONG argc;
  179. TEXT **argv;
  180. {
  181.     CFG  *cfg = &GlobCFG;
  182.     TEXT *pgmName = FilePart(argv[0]);
  183.  
  184.     bzero(cfg,sizeof(*cfg));
  185.  
  186.     cfg->cfg_fi = stdin;
  187.     cfg->cfg_fo = stdout;
  188.     cfg->cfg_fe = freopen("Console:","w+",stderr);
  189.  
  190.     if (cfg->cfg_fe)
  191.     {
  192.         int i;
  193.  
  194.         if (argv[1][0] == '?')
  195.         {
  196.             Usage(pgmName);
  197.             exit(1);
  198.         }
  199.  
  200.         for (i = 1 ; i < argc ; ++i)
  201.         {
  202.             TEXT *ptr = argv[i];
  203.  
  204.             if (*ptr == '-')
  205.             {
  206.                 ptr += 2;
  207.  
  208.                 switch (ToLower(ptr[-1]))
  209.                 {
  210.                     case 'c':
  211.                         cfg->cfg_case = TRUE;
  212.                         break;
  213.                     case 'i':
  214.                         if (*ptr)
  215.                             cfg->cfg_in = ptr;
  216.                         else
  217.                             cfg->cfg_in = argv[++i];
  218.                         break;
  219.                     case 'o':
  220.                         if (*ptr)
  221.                             cfg->cfg_out = ptr;
  222.                         else
  223.                             cfg->cfg_out = argv[++i];
  224.                         break;
  225.                     case 'r':
  226.                         if (*ptr)
  227.                             cfg->cfg_replace = ptr;
  228.                         else
  229.                             cfg->cfg_replace = argv[++i];
  230.                         break;
  231.                     case 's':
  232.                         if (*ptr)
  233.                             cfg->cfg_search = ptr;
  234.                         else
  235.                             cfg->cfg_search = argv[++i];
  236.                         break;
  237.                     case '0':
  238.                     case 'z':
  239.                     case 'n':    // Zero-alias not yet implemented...
  240.                         break;
  241.                     case 'v':
  242.                         cfg->cfg_verbose = TRUE;
  243.                         break;
  244.                     case 'a':
  245.                         About();
  246.                         exit(1);
  247.                     case '?':
  248.                     case 'h':
  249.                         Usage(pgmName);
  250.                         exit(1);
  251.                     default:
  252.                         fprintf(cfg->cfg_fe,"›33m%s:›0m Unrecognized option ›1m%c›0m\n",pgmName,ptr[-1]);
  253.                         Usage(pgmName);
  254.                         exit(5);
  255.                 }
  256.             }
  257.         }
  258.  
  259.         if (cfg->cfg_in && cfg->cfg_out)
  260.         {
  261.             if ((Stricmp(cfg->cfg_in,cfg->cfg_out) == 0) || (Stricmp(cfg->cfg_out,"-") == 0))
  262.             {
  263.                 long  len = strlen(cfg->cfg_in) + 3L;
  264.                 char *new = malloc(len);
  265.  
  266.                 if (new == NULL)
  267.                 {
  268.                     fprintf(cfg->cfg_fe,"›33m%s:›0m Insufficient memory!\n",pgmName);
  269.                     exit(20);
  270.                 }
  271.                 sprintf(new,"%s~",cfg->cfg_in);
  272.  
  273.                 if (Rename(cfg->cfg_in,new) == 0)
  274.                 {
  275.                     (VOID) DeleteFile(new);
  276.  
  277.                     if (Rename(cfg->cfg_in,new) == 0)
  278.                     {
  279.                         fprintf(cfg->cfg_fe,"›33m%s:›0m Can't rename ›3m%s›0m as ›3m%s›0m!\n",pgmName,cfg->cfg_in,new);
  280.                         exit(20);
  281.                     }
  282.                 }
  283.                 cfg->cfg_out = cfg->cfg_in;
  284.                 cfg->cfg_in     = new;
  285.             }
  286.         }
  287.  
  288.         if (cfg->cfg_in)
  289.             if ((cfg->cfg_fi = freopen(cfg->cfg_in,"r",stdin)) == NULL)
  290.                 BadFile(pgmName,"in",cfg->cfg_in);
  291.  
  292.         if (cfg->cfg_out)
  293.             if ((cfg->cfg_fo = freopen(cfg->cfg_out,"w",stdout)) == NULL)
  294.                 BadFile(pgmName,"out",cfg->cfg_out);
  295.  
  296.         if (cfg->cfg_search == NULL)
  297.             BadParm(pgmName,"search");
  298.  
  299.         cfg->cfg_search    = transmogrify(cfg->cfg_search);
  300.         cfg->cfg_slen    = strlen(cfg->cfg_search);
  301.  
  302.         if (cfg->cfg_replace == NULL)
  303.             BadParm(pgmName,"replace");
  304.  
  305.         cfg->cfg_replace = transmogrify(cfg->cfg_replace);
  306.         cfg->cfg_rlen     = strlen(cfg->cfg_replace);
  307.  
  308.         if (cfg->cfg_case)
  309.             cfg->cfg_comp = strncmp;
  310.         else
  311.             cfg->cfg_comp = strnicmp;
  312.  
  313.         return (cfg);
  314.     }
  315.     fprintf(cfg->cfg_fo,"›33m%s:›0m Error stream wouldn't open...\n",pgmName);
  316.     exit(20);
  317. }
  318.  
  319.  
  320. /*
  321. **    USAGE: Replace [-iinFile] [-ooutFile] <-ssearchStr> <-rreplaceStr> [-c] [-v]
  322. */
  323. void
  324. main(ac,av)
  325. int ac;
  326. char **av;
  327. {
  328.     CFG *cfg = InitCFG((LONG)ac,(TEXT **)av);
  329.     LONG  bsiz = RBUFSIZE-1;
  330.     TEXT *rbuf = RBuf;
  331.     TEXT *ptr;
  332.  
  333.     while (ptr = fgets(rbuf,bsiz,cfg->cfg_fi))
  334.     {
  335.         int slen = strlen(ptr);            
  336.         int ccnt = 0;
  337.  
  338.         while (ccnt < slen)
  339.         {
  340.             if (cfg->cfg_comp(cfg->cfg_search,&ptr[ccnt],cfg->cfg_slen) != 0)
  341.             {
  342.                 fputc(ptr[ccnt],cfg->cfg_fo);
  343.                 ++ccnt;
  344.             }
  345.             else
  346.             {
  347.                 fwrite(cfg->cfg_replace,1,cfg->cfg_rlen,cfg->cfg_fo);
  348.                 ++(cfg->cfg_count);
  349.                 ccnt += cfg->cfg_slen;
  350.             }
  351.         }
  352.     }
  353.  
  354.     if (cfg->cfg_verbose)
  355.     {
  356.         if (cfg->cfg_count)
  357.             fprintf(cfg->cfg_fe,"Replaced %ld occurrances of ›3m%s›0m with ›3m%s›0m\n",cfg->cfg_count,cfg->cfg_search,cfg->cfg_replace);
  358.         else
  359.             fprintf(cfg->cfg_fe,"No matches found...\n");
  360.     }
  361.     exit(0);
  362. }
  363.  
  364.  
  365. /*
  366. **    EOF
  367. */
  368.